package com.jwsoft.manager.core.integration.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.IdcardUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bifang.assistant.common.vo.SessionInfo;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.annotation.SaveOplog;
import com.bifang.engine.assistant.core.enums.AuTypeEnum;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.assistant.core.exception.AppException;
import com.bifang.engine.assistant.core.utils.SessionUtil;
import com.bifang.engine.data.core.util.PagerUtil;
import com.bifang.module.base.core.helper.DictHelper;
import com.bifang.module.system.core.dao.model.SysUser;
import com.bifang.module.system.core.dao.service.SysUserService;
import com.bifang.module.system.core.integration.UserIntegration;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.common.enums.*;
import com.jwsoft.manager.common.vo.eduWorkOrder.EduWorkOrderKeyVO;
import com.jwsoft.manager.common.vo.eduWorkOrder.EduWorkOrderQueryVO;
import com.jwsoft.manager.common.vo.eduWorkOrder.EduWorkOrderVO;
import com.jwsoft.manager.common.vo.eduWorkOrderLog.EduWorkOrderLogVO;
import com.jwsoft.manager.core.dao.model.EduWorkOrder;
import com.jwsoft.manager.core.dao.model.EduWorkOrderLog;
import com.jwsoft.manager.core.dao.service.EduWorkOrderLogService;
import com.jwsoft.manager.core.dao.service.EduWorkOrderService;
import com.jwsoft.manager.core.integration.EduWorkOrderIntegration;
import io.lettuce.core.RedisCommandExecutionException;
import lombok.extern.log4j.Log4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 工单表业务实现类
 *
 * @author zhiyuan
 * @since 2023-02-24
 */
@ApiService(funcCode = "workOrder", title = "工单表")
@Log4j
public class EduWorkOrderIntegrationImpl implements EduWorkOrderIntegration {

    @Autowired
    public EduWorkOrderService eduWorkOrderService;

    @Autowired
    public EduWorkOrderLogService eduWorkOrderLogService;

    @Autowired
    public DictHelper dictHelper;

    @Autowired
    public UserIntegration dictIntegration;
    @Autowired
    public SysUserService sysUserService;
    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    @OpApi(funcCode = "workOrder0001", title = "客服工单表分页查询", funcType = FuncTypeEnum.query, checkPrivilege = BoolEnum.FALSE)
    public PageInfo<EduWorkOrderVO> getList(EduWorkOrderQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        QueryWrapper<EduWorkOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(vo.getWorkNum() != null, EduWorkOrder::getWorkNum, vo.getWorkNum())
                .like(StringUtils.isNotBlank(vo.getWorkTitle()), EduWorkOrder::getWorkTitle, vo.getWorkTitle())
                .eq(StringUtils.isNotBlank(vo.getWorkStatus()), EduWorkOrder::getWorkStatus, vo.getWorkStatus())
                .eq(StringUtils.isNotBlank(vo.getWorkOrderType()), EduWorkOrder::getWorkOrderType, vo.getWorkOrderType())
                .in(!CollectionUtils.isEmpty(vo.getWorkStatusList()), EduWorkOrder::getWorkStatus, vo.getWorkStatusList())
                .eq(StringUtils.isNotBlank(vo.getIdcard()), EduWorkOrder::getIdcard, vo.getIdcard())
                .eq(StringUtils.isNotBlank(vo.getFullName()), EduWorkOrder::getFullName, vo.getFullName())
                .eq(StringUtils.isNotBlank(vo.getOnsiteSubmission()), EduWorkOrder::getOnsiteSubmission, vo.getOnsiteSubmission())
                .eq(!ObjectUtils.isEmpty(vo.getWorkDate()),  EduWorkOrder::getWorkDate, vo.getWorkDate())
                .eq(EduWorkOrder::getSubmitterId, SessionUtil.getUserId())//客服只能查看自己提交的工单
                .orderByDesc(EduWorkOrder::getCreateTime,EduWorkOrder::getWorkNum,EduWorkOrder::getWorkDate);

        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<EduWorkOrder> list = eduWorkOrderService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduWorkOrder> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduWorkOrderVO> resultList = Convert.toList(EduWorkOrderVO.class, pageInfo.getList());
        List<EduWorkOrderVO> collect = null;
        if (!ObjectUtils.isEmpty(resultList)) {
            collect = resultList.stream().map(item -> {
                item.setSubmitterOrgName(dictHelper.getOrgNameById(item.getSubmitterOrgId()));
                item.setHandleOrgName(dictHelper.getOrgNameById(item.getHandleOrgId()));
                SysUser user = sysUserService.getById(item.getHandleUserId());
                if (!ObjectUtils.isEmpty(user) && StringUtils.isNotBlank(user.getFullName())) {
                    item.setHandleUserName(user.getFullName());
                }
                return item;
            }).collect(Collectors.toList());
        }
        // 转义数据字典值
        dictHelper.valueToName(resultList, Arrays.asList(EduWorkOrderLogTypeDictEnum.values()));
        return PagerUtil.parsePagerVo(collect, pageInfo);
    }

    @Override
    @OpApi(funcCode = "workOrder0002", title = "工单表根据主键查询详情", funcType = FuncTypeEnum.query, checkPrivilege = BoolEnum.FALSE)
    public EduWorkOrderVO getById(EduWorkOrderKeyVO vo) {
        EduWorkOrder entity = eduWorkOrderService.getById(vo.getWorkOrderId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("查询不到详细信息!");
        }
        EduWorkOrderVO result = Convert.convert(EduWorkOrderVO.class, entity);
        return result;
    }

    /**
     * 保存前统一校验
     */
    @Override
    @OpApi(funcCode = "workOrder0003", title = "工单表保存前校验", funcType = FuncTypeEnum.other, checkPrivilege = BoolEnum.FALSE)
    public void checkSave(EduWorkOrderVO vo) {
        if (StringUtils.isBlank(vo.getWorkTitle())) {
            throw new AppException("标题不能为空！");
        }

        if (StringUtils.isBlank(vo.getSubmittedTo())) {
            throw new AppException("请选择提交给谁！");
        }

        if (StringUtils.isBlank(vo.getOnsiteSubmission())) {
            throw new AppException("是否现场提交不能为空！");
        }

        if (vo.getWorkNum() == null) {
            throw new AppException("工单序号不能为空！请刷新重试");
        }

        if (StringUtils.isNotBlank(vo.getIdcard()) && !IdcardUtil.isValidCard(vo.getIdcard())) {
            throw new AppException("学生身份证有误！");
        }

        if (StringUtils.isBlank(vo.getReturnVisits())) {
            vo.setReturnVisits("0");
        } else if ("1".equals(vo.getReturnVisits()) && StringUtils.isBlank(vo.getReturnTelephone())) {
            throw new AppException("请填写回访电话！");
        }

        if (StringUtils.isBlank(vo.getAreaCode())) {
            vo.setAreaCode(SessionUtil.getSessionInfo().getAreaCode());
        }

        if (ObjectUtils.isEmpty(vo.getWorkDate())){
            vo.setWorkDate(new Date());
        }
    }


    @Override
    @OpApi(funcCode = "workOrder0004", title = "工单表新增", funcType = FuncTypeEnum.insert, checkPrivilege = BoolEnum.FALSE)
    @SaveOplog(
            operationType = "workOrder0004",
            operationName = "工单表新增",
            dataType = "workOrderId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduWorkOrderVO add(EduWorkOrderVO vo) {
        //保存前校验
        checkSave(vo);
        //保存数据
        EduWorkOrder entity = Convert.convert(EduWorkOrder.class, vo);
        entity.setWorkHandleStatus(EduWorkHandleTypeEnum.dcl.getType());
        if (vo.getSubmittedTo().equals(EduWorkSubmittedToEnum.jjksh.getType())){
            entity.setWorkStatus(EduWorkTypeEnum.jjkdsh.getType());
        }else if (vo.getSubmittedTo().equals(EduWorkSubmittedToEnum.kzfs.getType())){
            entity.setWorkStatus(EduWorkTypeEnum.kzdsh.getType());
        }else if (vo.getSubmittedTo().equals(EduWorkSubmittedToEnum.jsrycl.getType())){
            entity.setWorkStatus(EduWorkTypeEnum.jsrydcl.getType());
        }
        entity.setSubmitterId(SessionUtil.getSessionInfo().getUserId());
        entity.setSubmitterName(SessionUtil.getSessionInfo().getFullName());
        entity.setSubmitterCellphone(SessionUtil.getSessionInfo().getCellphone());
        entity.setSubmitterOrgId(SessionUtil.getSessionInfo().getOrgId());
        eduWorkOrderService.save(entity);
        //将主键设置回vo使操作日志可以取到
        vo.setWorkOrderId(entity.getWorkOrderId());

        //添加工单日志
        saveEduWorkOrderLog(entity);
        return vo;
    }

    @Override
    @OpApi(funcCode = "workOrder0005", title = "工单表修改", funcType = FuncTypeEnum.update, checkPrivilege = BoolEnum.FALSE)
    @SaveOplog(
            operationType = "workOrder0005",
            operationName = "工单表修改",
            dataType = "workOrderId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduWorkOrderVO edit(EduWorkOrderVO vo) {
        if (ObjectUtils.isEmpty(vo.getWorkOrderId())) {
            throw new AppException("传入需要修改的主键不能为空!");
        }
        EduWorkOrder oldEntity = eduWorkOrderService.getById(vo.getWorkOrderId());
        if (ObjectUtils.isEmpty(oldEntity)) {
            throw new AppException("查询不到需要修改的信息!");
        }
        //保存前校验
        checkSave(vo);
        //保存数据
        EduWorkOrder entity = Convert.convert(EduWorkOrder.class, vo);
        //修改只能修改草稿状态工单，已提交的工单不能修改
        eduWorkOrderService.updateById(entity);
        return vo;
    }

    @Override
    @OpApi(funcCode = "workOrder0006", title = "工单表根据主键删除", funcType = FuncTypeEnum.delete, checkPrivilege = BoolEnum.FALSE)
    @SaveOplog(
            operationType = "workOrder0006",
            operationName = "工单表删除",
            dataType = "workOrderId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public void del(EduWorkOrderKeyVO vo) {
        if (ObjectUtils.isEmpty(vo.getWorkOrderId())) {
            throw new AppException("传入需要删除的数据主键不能为空!");
        }
        EduWorkOrder entity = eduWorkOrderService.getById(vo.getWorkOrderId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("未找到需要删除的信息!");
        }
        //工单删除只能删除技术还没有处理的工单
        if (!EduWorkHandleTypeEnum.dcl.getType().equals(entity.getWorkHandleStatus())){
            throw new AppException("技术人员已接单，不能撤销!");
        }
        eduWorkOrderService.removeById(vo.getWorkOrderId());
    }


    public void saveEduWorkOrderLog(EduWorkOrder oldEntity) {
        //保存工单表之后，需要向工单日志表插入流转信息
        EduWorkOrderLog log = new EduWorkOrderLog();
        log.setWorkOrderId(oldEntity.getWorkOrderId());
        //1.设置日志类型：工单提交
        log.setType(EduWorkLogTypeEnum.gdtj.getType());
        //工单提交，将提交人休息设置
        log.setUserId(SessionUtil.getSessionInfo().getUserId());
        log.setFullName(SessionUtil.getSessionInfo().getFullName());
        log.setOrgId(SessionUtil.getSessionInfo().getOrgId());
        log.setOrgName(dictHelper.getOrgNameById(SessionUtil.getSessionInfo().getOrgId()));
        //提交第一次保存，处理状态设置为，未处理
        log.setHandleStatus(EduWorkHandleTypeEnum.dcl.getType());
        log.setHandleTime(new Date());
        if (StringUtils.isNotBlank(oldEntity.getHandleMessage())) {
            log.setHandleMessage(oldEntity.getHandleMessage());
        }else {
            log.setHandleMessage("工单提交");
        }
        log.setNextUserId(oldEntity.getHandleUserId());
        log.setNextFullName(oldEntity.getHandleUserId());
        log.setNextOrgId(oldEntity.getHandleOrgId());
        log.setNextOrgName(dictHelper.getOrgNameById(oldEntity.getHandleOrgId()));
        //true 表示未最总节点
        log.setFinishFlag("0");
        eduWorkOrderLogService.save(log);
    }

    @Override
    @OpApi(funcCode = "workOrder0008", title = "技术人员工单处理分页查询", funcType = FuncTypeEnum.query, checkPrivilege = BoolEnum.FALSE)
    public PageInfo<EduWorkOrderVO> getWorkHandleList(EduWorkOrderQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        QueryWrapper<EduWorkOrder> queryWrapper = new QueryWrapper<>();
        //根据组织id或者处理人来进行查询
        queryWrapper.lambda()
                .eq(vo.getWorkNum() != null, EduWorkOrder::getWorkNum, vo.getWorkNum())
                .like(StringUtils.isNotBlank(vo.getWorkTitle()), EduWorkOrder::getWorkTitle, vo.getWorkTitle())
                .eq(StringUtils.isNotBlank(vo.getWorkStatus()), EduWorkOrder::getWorkStatus, vo.getWorkStatus())
                .eq(StringUtils.isNotBlank(vo.getWorkOrderType()), EduWorkOrder::getWorkOrderType, vo.getWorkOrderType())
                .in(!CollectionUtils.isEmpty(vo.getWorkStatusList()), EduWorkOrder::getWorkStatus, vo.getWorkStatusList())
                .eq(StringUtils.isNotBlank(vo.getHandleOrgId()), EduWorkOrder::getHandleOrgId, vo.getHandleOrgId())
                .eq(StringUtils.isNotBlank(vo.getIdcard()), EduWorkOrder::getIdcard, vo.getIdcard())
                .eq(StringUtils.isNotBlank(vo.getFullName()), EduWorkOrder::getFullName, vo.getFullName())
                .eq(StringUtils.isNotBlank(vo.getOnsiteSubmission()), EduWorkOrder::getOnsiteSubmission, vo.getOnsiteSubmission())
                .eq(!ObjectUtils.isEmpty(vo.getWorkDate()),  EduWorkOrder::getWorkDate, vo.getWorkDate())
                .orderByDesc(EduWorkOrder::getCreateTime,EduWorkOrder::getWorkNum,EduWorkOrder::getWorkDate);

        //如果传来的状态不是技术人员待处理，把人员加上，如果是技术人员待处理，直接查就行，不需要加人员
        if (!vo.getWorkStatusList().contains(EduWorkTypeEnum.jsrydcl.getType())){
            String userId = SessionUtil.getSessionInfo().getUserId();
            queryWrapper.inSql("work_order_id",
                    String.format("SELECT work_order_id FROM edu_work_order_log WHERE user_id = '%s'", userId)
            );
        }

        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<EduWorkOrder> list = eduWorkOrderService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduWorkOrder> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduWorkOrderVO> resultList = Convert.toList(EduWorkOrderVO.class, pageInfo.getList());
        List<EduWorkOrderVO> collect = resultList.stream().map(item -> {
            item.setSubmitterOrgName(dictHelper.getOrgNameById(item.getSubmitterOrgId()));
            item.setHandleOrgName(dictHelper.getOrgNameById(item.getHandleOrgId()));
            SysUser user = sysUserService.getById(item.getHandleUserId());
            if (!ObjectUtils.isEmpty(user) && StringUtils.isNotBlank(user.getFullName())) {
                item.setHandleUserName(user.getFullName());
            }
            return item;
        }).collect(Collectors.toList());

        // 转义数据字典值
        dictHelper.valueToName(resultList, Arrays.asList(EduWorkOrderLogTypeDictEnum.values()));
        return PagerUtil.parsePagerVo(collect, pageInfo);
    }

    @Override
    @OpApi(funcCode = "workOrder0009", title = "工单审核", funcType = FuncTypeEnum.update, checkPrivilege = BoolEnum.FALSE)
    @Transactional
    public void WorkOrderProcess(EduWorkOrderVO vo) {
        if (ObjectUtils.isEmpty(vo.getWorkOrderId())) {
            throw new AppException("传入需要修改的主键不能为空!");
        }
        EduWorkOrder entity = eduWorkOrderService.getById(vo.getWorkOrderId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("查询不到需要修改的信息!");
        }
        if (StringUtils.isEmpty(vo.getHandleMessage())) {
            throw new AppException("未输入处理描述!");
        }
        if (StringUtils.isEmpty(vo.getHandleStatus())) {
            throw new AppException("未选择处理意见!");
        }
        if (EduWorkHandleTypeEnum.ycl.getType().equals(entity.getWorkHandleStatus())) {
            throw new AppException("该工单是已处理状态!");
        }
        if ("1".equals(entity.getFinishFlag())) {
            throw new AppException("当前工单已结束，无法操作!");
        }
        UpdateWrapper<EduWorkOrder> updateWrapper = new UpdateWrapper<>();
        //需要判断当前操作人是不是 处理人 或者所属组织是不是指定的处理组织
        if (!SessionUtil.getSessionInfo().getAreaCode().equals(entity.getAreaCode())) {
            throw new AppException("处理人行政区划不数据此工单的行政区划，无法操作!");
        }

        updateWrapper.lambda()
                .eq(EduWorkOrder::getWorkOrderId, vo.getWorkOrderId());
        //将修改的值进行设置，调用修改方法，存入数据库
        updateWrapper.lambda()
                .set(EduWorkOrder::getHandleStatus, vo.getHandleStatus())
                .set(EduWorkOrder::getHandleMessage, vo.getHandleMessage())
                .set(EduWorkOrder::getHandleMaterial, vo.getHandleMaterial())
                .set(EduWorkOrder::getHandleOrgId, SessionUtil.getOrgId())
                .set(EduWorkOrder::getHandleUserId, SessionUtil.getSessionInfo().getUserId())
                .set(EduWorkOrder::getHandleTime, new Date())
                .set(EduWorkOrder::getWorkHandleStatus, EduWorkHandleTypeEnum.ycl.getType())
                .set(EduWorkOrder::getWorkStatus,  EduWorkTypeEnum.clwc.getType())
                .set(EduWorkOrder::getFinishFlag, "1");
        eduWorkOrderService.update(updateWrapper);

        //还需要根据工单id和用户id向日志表设置处理时间
        EduWorkOrderLog orderLog = new EduWorkOrderLog();
        orderLog.setWorkOrderId(entity.getWorkOrderId());
        orderLog.setType(EduWorkLogTypeEnum.gdcl.getType());
        orderLog.setUserId(SessionUtil.getSessionInfo().getUserId());
        orderLog.setFullName(SessionUtil.getSessionInfo().getFullName());
        orderLog.setOrgId(SessionUtil.getSessionInfo().getOrgId());
        orderLog.setOrgName(SessionUtil.getSessionInfo().getOrgName());
        orderLog.setHandleStatus(vo.getWorkHandleStatus());
        orderLog.setHandleTime(new Date());
        orderLog.setHandleMessage(vo.getHandleMessage());
        if (StringUtils.isNotBlank(vo.getNextOrgId()) && StringUtils.isNotBlank(vo.getNextUserId())) {
            orderLog.setNextOrgName(vo.getNextOrgId());
            orderLog.setNextOrgName(dictHelper.getOrgNameById(vo.getNextOrgId()));
            orderLog.setNextUserId(vo.getNextUserId());
            String fullName = sysUserService.getById(vo.getNextUserId()).getFullName();
            if (fullName != null) {
                orderLog.setNextFullName(fullName);
            }
        }
        eduWorkOrderLogService.save(orderLog);
    }


    @Override
    @OpApi(funcCode = "workOrder0010", title = "工单流转", funcType = FuncTypeEnum.update, checkPrivilege = BoolEnum.FALSE)
    @Transactional
    public void workOrderCirculation(EduWorkOrderLogVO vo) {
        if (ObjectUtils.isEmpty(vo.getWorkOrderId())) {
            throw new AppException("工单号不能为空！");
        }
        if (ObjectUtils.isEmpty(vo.getSubmittedTo())) {
            throw new AppException("转派的人员不能为空！");
        }
        EduWorkOrder entity = eduWorkOrderService.getById(vo.getWorkOrderId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("查询不到要流转的工单！");
        }

        //比对流转操作人是否为工单表指定的处理人或者处理组织
        SessionInfo sessionInfo = SessionUtil.getSessionInfo();
        if (!sessionInfo.getAreaCode().equals(entity.getAreaCode())) {
            throw new AppException("当前流转的工单不是本行政区划的，请联系管理员！");
        }
        if ("1".equals(entity.getFinishFlag())) {
            throw new AppException("当前工单已是最后节点，无法流转！");
        }

        //将修改信息插入日志
        EduWorkOrderLog workOrderLog = new EduWorkOrderLog();
        workOrderLog.setWorkOrderId(vo.getWorkOrderId());
        workOrderLog.setType(EduWorkLogTypeEnum.gdlz.getType());
        workOrderLog.setUserId(SessionUtil.getSessionInfo().getUserId());
        workOrderLog.setFullName(SessionUtil.getSessionInfo().getFullName());
        workOrderLog.setOrgId(SessionUtil.getSessionInfo().getOrgId());
        workOrderLog.setOrgName(SessionUtil.getSessionInfo().getOrgName());
        workOrderLog.setHandleTime(new Date());
        workOrderLog.setHandleMessage(vo.getHandleMessage());
        workOrderLog.setFinishFlag("0");
        eduWorkOrderLogService.save(workOrderLog);

        //修改工单信息
        UpdateWrapper<EduWorkOrder> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .eq(EduWorkOrder::getWorkOrderId, vo.getWorkOrderId())
                .set(EduWorkOrder::getFinishFlag, "0");

        if (vo.getSubmittedTo().equals(EduWorkSubmittedToEnum.jjksh.getType())){
            updateWrapper.lambda()
                    .set(EduWorkOrder::getWorkStatus, EduWorkTypeEnum.jjkdsh.getType())
                    .set(EduWorkOrder::getWorkHandleStatus, EduWorkHandleTypeEnum.dcl.getType());
        }else if (vo.getSubmittedTo().equals(EduWorkSubmittedToEnum.kzfs.getType())){
            updateWrapper.lambda()
                    .set(EduWorkOrder::getWorkStatus, EduWorkTypeEnum.kzdsh.getType())
                    .set(EduWorkOrder::getWorkHandleStatus, EduWorkHandleTypeEnum.dcl.getType());
        }else if (vo.getSubmittedTo().equals(EduWorkSubmittedToEnum.jsrycl.getType())){
            updateWrapper.lambda()
                    .set(EduWorkOrder::getWorkStatus, EduWorkTypeEnum.jsrydcl.getType())
                    .set(EduWorkOrder::getWorkHandleStatus, EduWorkHandleTypeEnum.dcl.getType());
        }
        eduWorkOrderService.update(updateWrapper);
    }


    @Override
    @OpApi(funcCode = "workOrder0011", title = "根据缓存获取序号", funcType = FuncTypeEnum.query, checkPrivilege = BoolEnum.FALSE)
    public Integer getWorkNum(EduWorkOrderKeyVO vo) {
        String today = LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);
        String cacheKey = "Edu_Work_Order_Num:" + today;
        String lockKey = "Edu_Work_Order_Lock:" + today;

        String lockValue = UUID.randomUUID().toString(); // 防止误删别人加的锁
        boolean locked = false;

        try {
            // 尝试加锁，过期时间 10 秒，避免死锁
            locked = Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, 10, TimeUnit.SECONDS));

            if (!locked) {
                throw new RuntimeException("获取序号失败，请稍后重试（被锁定）");
            }

            // 如果不存在则初始化
            Boolean exists = redisTemplate.hasKey(cacheKey);
            if (Boolean.FALSE.equals(exists)) {
                LocalDate newtoday = LocalDate.now();
                LocalDateTime startOfDay = newtoday.atStartOfDay(); // 今天 00:00:00
                LocalDateTime endOfDay = newtoday.plusDays(1).atStartOfDay(); // 明天 00:00:00

                QueryWrapper<EduWorkOrder> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda()
                        .ge(EduWorkOrder::getCreateTime, startOfDay)
                        .lt(EduWorkOrder::getCreateTime, endOfDay);
                queryWrapper.select("MAX(work_num) as work_num");
                EduWorkOrder maxOrder = eduWorkOrderService.getOne(queryWrapper);
                int initSerial = (maxOrder == null || maxOrder.getWorkNum() == null) ? 0 : maxOrder.getWorkNum();

                redisTemplate.opsForValue().set(cacheKey, initSerial, 24, TimeUnit.HOURS);
            }

            Long newSerial = redisTemplate.opsForValue().increment(cacheKey, 1);
            return newSerial.intValue();

        } catch (RedisCommandExecutionException e) {
            redisTemplate.delete(cacheKey);
            throw new RuntimeException("Redis 缓存格式异常，已清除缓存，请重试", e);
        } finally {
            // 释放锁：确保只有自己加的锁才能删
            try {
                String currentValue = (String) redisTemplate.opsForValue().get(lockKey);
                if (lockValue.equals(currentValue)) {
                    redisTemplate.delete(lockKey);
                }
            } catch (Exception ex) {
                // 日志记录即可，避免影响主流程
                log.error("释放Redis分布式锁失败", ex);
            }
        }
    }

    @Override
    @OpApi(funcCode = "workOrder0012", title = "技术人员接单", funcType = FuncTypeEnum.delete, checkPrivilege = BoolEnum.FALSE)
    public void acceptOrder(EduWorkOrderKeyVO vo) {
        if (ObjectUtils.isEmpty(vo.getWorkOrderId())) {
            throw new AppException("传入接单数据主键不能为空!");
        }
        EduWorkOrder entity = eduWorkOrderService.getById(vo.getWorkOrderId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("未找到需要接单的信息!");
        }
        if (!EduWorkTypeEnum.jsrydcl.getType().equals(entity.getWorkStatus())){
            throw new AppException("当前工单状态不是技术人员待处理，无法接单！");
        }
        if (!EduWorkHandleTypeEnum.dcl.getType().equals(entity.getWorkHandleStatus())){
            throw new AppException("当前工单状态不是待处理，无法接单！");
        }
        entity.setWorkHandleStatus(EduWorkHandleTypeEnum.clz.getType());
        entity.setWorkStatus(EduWorkTypeEnum.clz.getType());
        eduWorkOrderService.updateById(entity);

        //将接单信息插入日志
        EduWorkOrderLog workOrderLog = new EduWorkOrderLog();
        workOrderLog.setWorkOrderId(vo.getWorkOrderId());
        workOrderLog.setType(EduWorkLogTypeEnum.jd.getType());
        workOrderLog.setUserId(SessionUtil.getSessionInfo().getUserId());
        workOrderLog.setFullName(SessionUtil.getSessionInfo().getFullName());
        workOrderLog.setOrgId(SessionUtil.getSessionInfo().getOrgId());
        workOrderLog.setOrgName(SessionUtil.getSessionInfo().getOrgName());
        workOrderLog.setHandleTime(new Date());
        workOrderLog.setHandleMessage("技术人员接单");
        workOrderLog.setFinishFlag("0");
        eduWorkOrderLogService.save(workOrderLog);
    }

    @Override
    @OpApi(funcCode = "workOrder0013", title = "学校工单表分页查询", funcType = FuncTypeEnum.query, checkPrivilege = BoolEnum.FALSE)
    public PageInfo<EduWorkOrderVO> getListSchool(EduWorkOrderQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        QueryWrapper<EduWorkOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(vo.getWorkNum() != null, EduWorkOrder::getWorkNum, vo.getWorkNum())
                .like(StringUtils.isNotBlank(vo.getWorkTitle()), EduWorkOrder::getWorkTitle, vo.getWorkTitle())
                .eq(StringUtils.isNotBlank(vo.getWorkStatus()), EduWorkOrder::getWorkStatus, vo.getWorkStatus())
                .eq(StringUtils.isNotBlank(vo.getWorkOrderType()), EduWorkOrder::getWorkOrderType, vo.getWorkOrderType())
                .in(!CollectionUtils.isEmpty(vo.getWorkStatusList()), EduWorkOrder::getWorkStatus, vo.getWorkStatusList())
                .eq(StringUtils.isNotBlank(vo.getIdcard()), EduWorkOrder::getIdcard, vo.getIdcard())
                .eq(StringUtils.isNotBlank(vo.getFullName()), EduWorkOrder::getFullName, vo.getFullName())
                .eq(StringUtils.isNotBlank(vo.getOnsiteSubmission()), EduWorkOrder::getOnsiteSubmission, vo.getOnsiteSubmission())
                .eq(!ObjectUtils.isEmpty(vo.getWorkDate()),  EduWorkOrder::getWorkDate, vo.getWorkDate())
                .eq(EduWorkOrder::getSubmitterOrgId, SessionUtil.getOrgId())//学校只能查看自己学校的工单
                .orderByDesc(EduWorkOrder::getCreateTime,EduWorkOrder::getWorkNum,EduWorkOrder::getWorkDate);

        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<EduWorkOrder> list = eduWorkOrderService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduWorkOrder> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduWorkOrderVO> resultList = Convert.toList(EduWorkOrderVO.class, pageInfo.getList());
        List<EduWorkOrderVO> collect = null;
        if (!ObjectUtils.isEmpty(resultList)) {
            collect = resultList.stream().map(item -> {
                item.setSubmitterOrgName(dictHelper.getOrgNameById(item.getSubmitterOrgId()));
                item.setHandleOrgName(dictHelper.getOrgNameById(item.getHandleOrgId()));
                SysUser user = sysUserService.getById(item.getHandleUserId());
                if (!ObjectUtils.isEmpty(user) && StringUtils.isNotBlank(user.getFullName())) {
                    item.setHandleUserName(user.getFullName());
                }
                return item;
            }).collect(Collectors.toList());
        }
        // 转义数据字典值
        dictHelper.valueToName(resultList, Arrays.asList(EduWorkOrderLogTypeDictEnum.values()));
        return PagerUtil.parsePagerVo(collect, pageInfo);
    }

    @Override
    @OpApi(funcCode = "workOrder0014", title = "基教科工单处理分页查询", funcType = FuncTypeEnum.query, checkPrivilege = BoolEnum.FALSE)
    public PageInfo<EduWorkOrderVO> gethandleWorkBasicEduDept(EduWorkOrderQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        String userId = SessionUtil.getSessionInfo().getUserId();

        QueryWrapper<EduWorkOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(vo.getWorkNum() != null, EduWorkOrder::getWorkNum, vo.getWorkNum())
                .like(StringUtils.isNotBlank(vo.getWorkTitle()), EduWorkOrder::getWorkTitle, vo.getWorkTitle())
                .eq(StringUtils.isNotBlank(vo.getWorkStatus()), EduWorkOrder::getWorkStatus, vo.getWorkStatus())
                .in(!CollectionUtils.isEmpty(vo.getWorkStatusList()), EduWorkOrder::getWorkStatus, vo.getWorkStatusList())
                .eq(StringUtils.isNotBlank(vo.getHandleOrgId()), EduWorkOrder::getHandleOrgId, vo.getHandleOrgId())
                .eq(StringUtils.isNotBlank(vo.getOnsiteSubmission()), EduWorkOrder::getOnsiteSubmission, vo.getOnsiteSubmission())
                .eq(!ObjectUtils.isEmpty(vo.getWorkDate()),  EduWorkOrder::getWorkDate, vo.getWorkDate())
                .orderByDesc(EduWorkOrder::getCreateTime,EduWorkOrder::getWorkNum,EduWorkOrder::getWorkDate);

        //如果传来的状态不是基教科待审核，把人员加上，如果是基教科待审核，直接查就行，不需要加人员
        if (!vo.getWorkStatusList().contains(EduWorkTypeEnum.jjkdsh.getType())){
            queryWrapper.inSql("work_order_id",
                    String.format("SELECT work_order_id FROM edu_work_order_log WHERE user_id = '%s'", userId)
            );
        }

        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<EduWorkOrder> list = eduWorkOrderService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduWorkOrder> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduWorkOrderVO> resultList = Convert.toList(EduWorkOrderVO.class, pageInfo.getList());
        List<EduWorkOrderVO> collect = resultList.stream().map(item -> {
            item.setSubmitterOrgName(dictHelper.getOrgNameById(item.getSubmitterOrgId()));
            item.setHandleOrgName(dictHelper.getOrgNameById(item.getHandleOrgId()));
            SysUser user = sysUserService.getById(item.getHandleUserId());
            if (!ObjectUtils.isEmpty(user) && StringUtils.isNotBlank(user.getFullName())) {
                item.setHandleUserName(user.getFullName());
            }
            return item;
        }).collect(Collectors.toList());

        // 转义数据字典值
        dictHelper.valueToName(resultList, Arrays.asList(EduWorkOrderLogTypeDictEnum.values()));
        return PagerUtil.parsePagerVo(collect, pageInfo);
    }

    @Override
    @OpApi(funcCode = "workOrder0015", title = "科长工单处理分页查询", funcType = FuncTypeEnum.query, checkPrivilege = BoolEnum.FALSE)
    public PageInfo<EduWorkOrderVO> gethandleWorkSectionChief(EduWorkOrderQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        String userId = SessionUtil.getSessionInfo().getUserId();

        QueryWrapper<EduWorkOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(vo.getWorkNum() != null, EduWorkOrder::getWorkNum, vo.getWorkNum())
                .like(StringUtils.isNotBlank(vo.getWorkTitle()), EduWorkOrder::getWorkTitle, vo.getWorkTitle())
                .eq(StringUtils.isNotBlank(vo.getWorkStatus()), EduWorkOrder::getWorkStatus, vo.getWorkStatus())
                .in(!CollectionUtils.isEmpty(vo.getWorkStatusList()), EduWorkOrder::getWorkStatus, vo.getWorkStatusList())
                .eq(StringUtils.isNotBlank(vo.getHandleOrgId()), EduWorkOrder::getHandleOrgId, vo.getHandleOrgId())
                .eq(StringUtils.isNotBlank(vo.getOnsiteSubmission()), EduWorkOrder::getOnsiteSubmission, vo.getOnsiteSubmission())
                .eq(!ObjectUtils.isEmpty(vo.getWorkDate()),  EduWorkOrder::getWorkDate, vo.getWorkDate())
                .orderByDesc(EduWorkOrder::getCreateTime,EduWorkOrder::getWorkNum,EduWorkOrder::getWorkDate);

        //如果传来的状态不是基教科待审核，把人员加上，如果是基教科待审核，直接查就行，不需要加人员

        if (!vo.getWorkStatusList().contains(EduWorkTypeEnum.kzdsh.getType())){
            queryWrapper.inSql("work_order_id",
                    String.format("SELECT work_order_id FROM edu_work_order_log WHERE user_id = '%s'", userId)
            );
        }

        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<EduWorkOrder> list = eduWorkOrderService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduWorkOrder> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduWorkOrderVO> resultList = Convert.toList(EduWorkOrderVO.class, pageInfo.getList());
        List<EduWorkOrderVO> collect = resultList.stream().map(item -> {
            item.setSubmitterOrgName(dictHelper.getOrgNameById(item.getSubmitterOrgId()));
            item.setHandleOrgName(dictHelper.getOrgNameById(item.getHandleOrgId()));
            SysUser user = sysUserService.getById(item.getHandleUserId());
            if (!ObjectUtils.isEmpty(user) && StringUtils.isNotBlank(user.getFullName())) {
                item.setHandleUserName(user.getFullName());
            }
            return item;
        }).collect(Collectors.toList());

        // 转义数据字典值
        dictHelper.valueToName(resultList, Arrays.asList(EduWorkOrderLogTypeDictEnum.values()));
        return PagerUtil.parsePagerVo(collect, pageInfo);
    }

    @Override
    @OpApi(funcCode = "workOrder0016", title = "所有工单处理分页查询", funcType = FuncTypeEnum.query, checkPrivilege = BoolEnum.FALSE)
    public PageInfo<EduWorkOrderVO> getWorkOrderAll(EduWorkOrderQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        QueryWrapper<EduWorkOrder> queryWrapper = new QueryWrapper<>();
        //根据组织id或者处理人来进行查询
        queryWrapper.lambda()
                .eq(vo.getWorkNum() != null, EduWorkOrder::getWorkNum, vo.getWorkNum())
                .like(StringUtils.isNotBlank(vo.getWorkTitle()), EduWorkOrder::getWorkTitle, vo.getWorkTitle())
                .eq(StringUtils.isNotBlank(vo.getWorkStatus()), EduWorkOrder::getWorkStatus, vo.getWorkStatus())
                .eq(StringUtils.isNotBlank(vo.getWorkOrderType()), EduWorkOrder::getWorkOrderType, vo.getWorkOrderType())
                .in(!CollectionUtils.isEmpty(vo.getWorkStatusList()), EduWorkOrder::getWorkStatus, vo.getWorkStatusList())
                .eq(StringUtils.isNotBlank(vo.getHandleOrgId()), EduWorkOrder::getHandleOrgId, vo.getHandleOrgId())
                .eq(StringUtils.isNotBlank(vo.getIdcard()), EduWorkOrder::getIdcard, vo.getIdcard())
                .eq(StringUtils.isNotBlank(vo.getFullName()), EduWorkOrder::getFullName, vo.getFullName())
                .eq(StringUtils.isNotBlank(vo.getOnsiteSubmission()), EduWorkOrder::getOnsiteSubmission, vo.getOnsiteSubmission())
                .eq(!ObjectUtils.isEmpty(vo.getWorkDate()),  EduWorkOrder::getWorkDate, vo.getWorkDate())
                .orderByDesc(EduWorkOrder::getCreateTime,EduWorkOrder::getWorkNum,EduWorkOrder::getWorkDate);

        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<EduWorkOrder> list = eduWorkOrderService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduWorkOrder> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduWorkOrderVO> resultList = Convert.toList(EduWorkOrderVO.class, pageInfo.getList());
        List<EduWorkOrderVO> collect = resultList.stream().map(item -> {
            item.setSubmitterOrgName(dictHelper.getOrgNameById(item.getSubmitterOrgId()));
            item.setHandleOrgName(dictHelper.getOrgNameById(item.getHandleOrgId()));
            SysUser user = sysUserService.getById(item.getHandleUserId());
            if (!ObjectUtils.isEmpty(user) && StringUtils.isNotBlank(user.getFullName())) {
                item.setHandleUserName(user.getFullName());
            }
            return item;
        }).collect(Collectors.toList());

        // 转义数据字典值
        dictHelper.valueToName(resultList, Arrays.asList(EduWorkOrderLogTypeDictEnum.values()));
        return PagerUtil.parsePagerVo(collect, pageInfo);
    }


    @Override
    @OpApi(funcCode = "workOrder0017", title = "现场查询工单表分页查询", funcType = FuncTypeEnum.query, checkPrivilege = BoolEnum.FALSE)
    public PageInfo<EduWorkOrderVO> workSubmitxcck(EduWorkOrderQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        if(vo.getWorkDate()==null){
            vo.setWorkDate(new Date());
        }
        QueryWrapper<EduWorkOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .select(EduWorkOrder::getWorkNum,EduWorkOrder::getWorkOrderId)
                .eq(StringUtils.isNotBlank(vo.getOnsiteSubmission()), EduWorkOrder::getOnsiteSubmission, vo.getOnsiteSubmission())
                .in(!CollectionUtils.isEmpty(vo.getWorkStatusList()), EduWorkOrder::getWorkStatus, vo.getWorkStatusList())
                .eq(!ObjectUtils.isEmpty(vo.getWorkDate()),  EduWorkOrder::getWorkDate, vo.getWorkDate())
                .orderByDesc(EduWorkOrder::getCreateTime,EduWorkOrder::getWorkNum,EduWorkOrder::getWorkDate);
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<EduWorkOrder> list = eduWorkOrderService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduWorkOrder> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduWorkOrderVO> resultList = Convert.toList(EduWorkOrderVO.class, pageInfo.getList());
        // 转义数据字典值
        // dictHelper.valueToName(resultList, Arrays.asList(EduWorkOrderLogTypeDictEnum.values()));
        return PagerUtil.parsePagerVo(resultList, pageInfo);
    }
}
